﻿using System;
using System.Collections.Concurrent;
using System.Linq;
using Charades.Web.Helpers;
using Charades.Web.Server.User;

using Charades.Web.Server.Round;

namespace Charades.Web.Server.Room
{
	public class RoomHandler
	{
		private readonly ConcurrentDictionary<string, Room> roomList;

		public RoomHandler(UserHandler userHandler, object locker)
		{
			this.roomList = new ConcurrentDictionary<string, Room>();
		}

		public Room FindRoom(string roomId)
		{
			Room room = null;

			if (string.IsNullOrEmpty(roomId))
			{
				room =
					this.roomList.OrderBy(r => r.Value.Users.Count)
						.FirstOrDefault(
							r => !r.Value.IsPrivate &&
							     r.Value.Users.Count > 0 && r.Value.Users.Count < ServerSettings.MaxRoomSize &&
							     r.Value.Status != RoomStatus.Finished)
						.Value ?? this.CreateRoom();
			}
			else
			{
				room =
					this.roomList.FirstOrDefault(
						r => r.Value.Id == roomId && r.Value.Status != RoomStatus.Finished).Value;
			}

			return room;
		}

		public Room CreateRoom(string roomId = "")
		{
			var room = new Room(roomId);
			this.roomList.TryAdd(room.Id, room);
			ElmahLogger.LogMessage(String.Format("Новая комната создана. Всего {0} комнат запущено.",
				this.roomList.Count(r => r.Value.Status == RoomStatus.Started)));
			if (string.IsNullOrEmpty(roomId))
			{
				YoHelper.SendYo();
			}
			RoomCreatingTimer.StartTimer();

			return room;
		}

		public bool CheckRoom(string roomId)
		{
			return !string.IsNullOrEmpty(roomId) && this.roomList.Any(r => r.Value.Id == roomId && r.Value.Status != RoomStatus.Finished);
		}

		public Room GetRoom(string connectionId)
		{
			return this.roomList.OrderByDescending(r => r.Value.Date).FirstOrDefault(r => r.Value.Users.Any(u => u.ConnectionId == connectionId)).Value;
		}

		public void RemoveUser(string connectionId)
		{
			var room = GetRoom(connectionId);
			if (room != null)
			{
				var user = room.Users.First(u => u.ConnectionId == connectionId);
				room.Users.Remove(user);
				if (room.Users.Count < ServerSettings.MinRoomSize)// < потому что данный пользователь уже удален
				{
					this.roomList.TryRemove(room.Id, out room);
					room.Status = RoomStatus.Finished;
				}
			}
		}

		public bool UserCanDraw(string connectionId)
		{
			var result = false;
			var room = this.GetRoom(connectionId);
			if (room != null)
			{
				var round = room.Rounds.FirstOrDefault(r => r.User.ConnectionId == connectionId && r.State == RoundState.Started);
				if (round != null)
				{
					result = true;
				}
			}
			return result;
		}
	}
}